package com.ruoyi.web.controller.delivery;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.jianqiao.delivery.ai.domain.DocInfoEntity;
import com.jianqiao.delivery.ai.domain.StreamDataEntity;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * author: cyx
 * create: 2024/7/31 11:54
 **/
@RestController
@RequestMapping("/ai")
@Slf4j
public class AiController {

    @Value("${ai.create}")
    private String createUrl;
    @Value("${ai.sendMessage}")
    private String sendMessageUrl;
    @Value("${ai.stream}")
    private String streamUrl;
    @Value("${ai.history}")
    private String historyUrl;

    @GetMapping("/create")
    public Map<String ,Object> createAi(){
        String bodyJson = "{\"customerUuid\":\"91cd6e6d3eb7dd3297e8af938b5b8c59\"}";
        String response = HttpClientUtil.doPostJson(createUrl, bodyJson);
        log.info("创建ai聊天响应->" + response);

        Map<String, Object> responseMap = JSONObject.parseObject(response).getInnerMap();

        String data = JSONObject.parseObject(response).getString("data");
        String isContext = JSONObject.parseObject(data).getString("isContext");
        Map<String, Object> dataMap = JSONObject.parseObject(data).getInnerMap();
        dataMap.put("isContext" ,isContext);

        responseMap.put("data" ,dataMap);

        return responseMap;
    }

    @PostMapping("/history")
    public Map<String ,Object> historyAi(@RequestBody Map<String ,String> param) throws JsonProcessingException {
        Map<String, String> headMap = new HashMap<>();
        headMap.put("Content-Type" ,"application/json");
        Map<String, Object> resultMap = HttpClientUtil.doGet(historyUrl, param, headMap);
        log.info("AI窗口历史列表->" + resultMap);

        String responseString = resultMap.get("resultString").toString();
        String row = JSONObject.parseObject(responseString).getString("rows");
        ObjectMapper objectMapper = new ObjectMapper();
        List rowList = objectMapper.readValue(row, List.class);

        Map<String, Object> responseMap = JSONObject.parseObject(responseString).getInnerMap();
        responseMap.put("rows" ,rowList);
        return responseMap;
    }

    @PostMapping("/sendMessage")
    public Map<String ,Object> sendMessage(@RequestBody Map<String ,String> param) throws JsonProcessingException {
        String customerUuid = param.get("customerUuid");
        String message = param.get("message");
        String role = param.get("role");
        String windowId = param.get("windowId");
        String bodyJson = "{\"customerUuid\":\"" + customerUuid + "\"," +
                          "\"message\":\"" + message + "\"," +
                          "\"role\":\"" + role + "\"," +
                          "\"windowId\":\"" + windowId + "\"}";
        String responseStr = HttpClientUtil.doPostJson(sendMessageUrl, bodyJson);

        Map<String, Object> responseMap = JSONObject.parseObject(responseStr).getInnerMap();
        String data = JSONObject.parseObject(responseStr).getString("data");
        Map<String, Object> dataMap = JSONObject.parseObject(data).getInnerMap();
        String docInfo = JSONObject.parseObject(data).getString("docInfo");
        ObjectMapper objectMapper = new ObjectMapper();
        List docInfoList = objectMapper.readValue(docInfo, List.class);
        dataMap.put("docInfo" ,docInfoList);
        responseMap.put("data" ,dataMap);

        return responseMap;
    }

//    @GetMapping(value = "/stream" ,produces = "application/stream+json")
    @GetMapping(value = "/stream" ,produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Map<String, Object>> stream(String customerUuid , String windowId) throws JsonProcessingException, IllegalAccessException {

        Gson gson = new Gson();

        HashMap<String, String> param = new HashMap<>();
        Map<String, String> headMap = new HashMap<>();
        param.put("customerUuid" ,customerUuid);
        param.put("windowId" ,windowId);
        headMap.put("Content-Type" ,"application/json");
        Map<String, Object> resultMap = HttpClientUtil.doGet(streamUrl, param, headMap);
        String resultString = resultMap.get("resultString").toString();
        String outEventStr = resultString.replaceAll("event: message\\s*", "").trim();

        String newResultStr = outEventStr.replace("data: ", "");
        List<String> stringList = new ArrayList<>();
        stringList.add(newResultStr);
        String string = stringList.toString().replace("\n" ,",");
        String replace = string.replace(",,", ",");
        List<StreamDataEntity> streamDataEntities = JSON.parseArray(replace, StreamDataEntity.class);
        List<String> messages = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
//        HashMap<String, StreamDataEntity> jsonMap = new HashMap<>();
        for(int i = 0 ;i < streamDataEntities.size() ;i ++) {
            StreamDataEntity streamDataEntity = streamDataEntities.get(i);
            List<DocInfoEntity> docInfoList = streamDataEntity.getDocInfo();
            String docStr = objectMapper.writeValueAsString(docInfoList);
            streamDataEntity.setDocInfoStr(docStr);
            String value = objectMapper.writeValueAsString(streamDataEntity);
//            String tempJsonOne = streamDataEntities.get(i).toString().replace("StreamDataEntity(" ,"");
//            int lastIndex = tempJsonOne.lastIndexOf(")");
//            String tempJsonTow = tempJsonOne.substring(0, lastIndex);
//            Map jsonMap = objectMapper.readValue(tempJsonTow, Map.class);
//            String docInfo = JSONObject.parseObject(tempJsonTow).getString("docInfo");
//            List docList = objectMapper.readValue(docInfo, List.class);

            messages.add(value);
        }

        Stream<Map<String, Object>> messageStream = messages.stream()
                .map(message -> {
                    try {
                        // 将 JSON 字符串解析为 JsonNode，然后转换为 Map
                        JsonNode jsonNode = objectMapper.readTree(message);
                        return objectMapper.convertValue(jsonNode, Map.class);
                    } catch (IOException e) {
                        log.error("Error parsing JSON: {}", message, e);
                        return null; // 或者抛出一个异常，取决于您的错误处理策略
                    }
                });
//        Stream<String> eventMessageStream = messages.stream();
//        Stream<Map.Entry<String, String>> entryStream = eventMessageStream.map(s -> {
//            String[] parts = s.split(":", 2);
//            if (parts.length == 2) {
//                return new AbstractMap.SimpleEntry<>(parts[0], parts[1]);
//            } else {
//                // 处理分割失败的情况，这里只是返回null，实际中可能需要抛出异常或记录错误
//                return null;
//            }
//        });

//        Function<String, String[]> splitFunction = s -> s.split(":", 2);

        // 使用map转换流中的每个元素，这里我们将每个字符串转换为一个包含两部分的字符串数组
//        Stream<String[]> eventMessagePartsStream = eventMessageStream.map(splitFunction);
//        Flux<Map.Entry<String, String>> entryFlux = Flux.fromStream(
//                entryStream.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
//                        .entrySet().stream() // 注意：这里将Map的entrySet转换为Stream，因为Flux.fromStream需要一个Stream
//        );
        log.info("执行了事件流");
        return Flux.fromStream(messageStream);
    }

    public Map<String, Object> entityToMap(StreamDataEntity streamDataEntity) throws IllegalAccessException {
        Map<String, Object> resultMap = new HashMap<>();
        Field[] declaredFields = streamDataEntity.getClass().getDeclaredFields();
        for (Field field : declaredFields){
            field.setAccessible(true);
            String fieldName = field.getName();
            Object fieldValue = field.get(streamDataEntity);
            resultMap.put(fieldName ,fieldValue);
        }
        return resultMap;
    }
}
